#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>

volatile sig_atomic_t progress_flag = 0;  // 原子标志位
long total_bytes = 0;                     // 总复制字节数
long file_size = 0;                       // 文件总大小

// 父进程信号处理函数
void sigusr1_handler(int sig) {
    progress_flag = 1;  // 设置进度打印标志
}

// 子进程信号处理函数
void sigalrm_handler(int sig) {
    kill(getppid(), SIGUSR1);  // 向父进程发送SIGUSR1
}

int main() {
    const char* src = "/home/bzsg/下载/monitorRos.zip";
    const char* dest = "/home/bzsg/monitorRos.zip";
    struct stat st;
    
    // 获取源文件大小
    if (stat(src, &st) == -1) {
        perror("stat failed");
        exit(EXIT_FAILURE);
    }
    file_size = st.st_size;
    
    // 设置父进程信号处理器
    struct sigaction sa;
    sa.sa_handler = sigusr1_handler;
    sa.sa_flags = SA_RESTART;  // 自动重启被中断的系统调用
    sigemptyset(&sa.sa_mask);
    sigaction(SIGUSR1, &sa, NULL);

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) {  // 子进程
        // 设置SIGALRM处理器
        sa.sa_handler = sigalrm_handler;
        sigaction(SIGALRM, &sa, NULL);
        ualarm(100000, 10000); // 参数为微秒(1秒=10^6微秒)
        while(1) pause();  // 等待信号
    } 
    else {  // 父进程
        int src_fd = open(src, O_RDONLY);
        int dest_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0644);
        
        if (src_fd == -1 || dest_fd == -1) {
            perror("file open failed");
            exit(EXIT_FAILURE);
        }

        char buffer[256];
        ssize_t bytes_read;
        
        printf("Parent[%d] copying %s (%ld bytes)\n", getpid(), src, file_size);
        printf("Child[%d] will report progress every 0.5s\n", pid);
        
        while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0) {
            // 写入目标文件
            ssize_t bytes_written = write(dest_fd, buffer, bytes_read);
            if (bytes_written < bytes_read) {
                perror("write error");
                break;
            }
            
            total_bytes += bytes_written;
            
            // 检查进度打印标志
            if (progress_flag) {
                printf("Progress: %.2f%% (%ld/%ld bytes)\n", 
                      (double)total_bytes/file_size * 100, 
                      total_bytes, file_size);
                progress_flag = 0;  // 重置标志
            }
        }
        
        // 复制完成处理
        printf("\nCopy complete! Terminating child process...\n");
        kill(pid, SIGTERM);  // 终止子进程
        wait(NULL);          // 等待子进程退出
        
        close(src_fd);
        close(dest_fd);
    }
    return 0;
}
